package com.paic.mhis.hcpms.audit.biz.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.paic.mhis.common.base.dto.PaginationDTO;
import com.paic.mhis.common.base.intergration.dao.CommonDAO;
import com.paic.mhis.common.util.BusinessServiceUtil;
import com.paic.mhis.core.auth.biz.service.Authority;
import com.paic.mhis.core.auth.biz.service.UserDetails;
import com.paic.mhis.hcpms.agreement.healthcareprovider.util.Constants;
import com.paic.mhis.hcpms.audit.biz.service.AuditOpinionService;
import com.paic.mhis.hcpms.audit.biz.service.AuditProblemsService;
import com.paic.mhis.hcpms.audit.biz.service.AuditWorkFlowService;
import com.paic.mhis.hcpms.audit.biz.service.RandomCodeService;
import com.paic.mhis.hcpms.audit.constants.AuditConstants;
import com.paic.mhis.hcpms.audit.dao.AuditDao;
import com.paic.mhis.hcpms.audit.dao.AuditProblemDao;
import com.paic.mhis.hcpms.audit.dto.AuditOpinionDTO;
import com.paic.mhis.hcpms.audit.dto.AuditProblemsDTO;
import com.paic.mhis.hcpms.audit.dto.AuditTargetDTO;
import com.paic.mhis.hcpms.audit.util.AuditWfContentsUtil;
import com.paic.mhis.hcpms.audit.util.EventCodeUtil;
import com.paic.mhis.hcpms.common.base.dto.PaginatedQueryDTO;
import com.paic.mhis.hcpms.common.storage.biz.service.HcpmsStorageService;
import com.paic.mhis.hcpms.common.storage.biz.service.StorageService;
import com.paic.mhis.hcpms.common.storage.dto.HcpmsStorageDTO;
import com.paic.mhis.hcpms.common.storage.dto.HcpmsStorageDataDTO;
import com.paic.mhis.hcpms.common.workflow.vo.HcpmsWorkFlowVO;
import com.paic.mhis.hcpms.trust.biz.service.IntegrityMedicalService;
import com.paic.pafa.app.biz.service.BusinessServiceException;
import com.paic.pafa.exceptions.BusinessException;

/**
 * 
 * @author EX-CAOTIANHUA001
 * 
 */
@Service("auditProblemsService")
public class AuditProblemsServiceImpl implements AuditProblemsService {

	@Autowired
	private CommonDAO commonDAO;

	@Autowired
	private AuditDao auditDao;

	@Autowired
	private AuditProblemDao auditProblemDao;

	@Autowired
	private AuditOpinionService auditOpinionService;

	@Autowired
	private AuditWorkFlowService auditWorkFlowService; // 流程

	@Autowired
	private IntegrityMedicalService integrityMedicalService;

	@Autowired
	private RandomCodeService randomCodeService;

	@Autowired
	private StorageService storageService;

	@Autowired
	private HcpmsStorageService hcpmsStorageService;

	@Override
	@Transactional(rollbackFor = BusinessServiceException.class)
	public Map<String, Object> saveAuditProblems(JSONObject json,
			UserDetails user) throws BusinessServiceException {
		Map<String, Object> resultMap = null;
		try {
			AuditProblemsDTO dto = JSONObject.toJavaObject(json,
					AuditProblemsDTO.class);
			resultMap = new HashMap<String, Object>();
			if (dto.getProblemCode() != null
					&& !"".equals(dto.getProblemCode().trim())) {
				initWf(user, dto);
				AuditOpinionDTO odto = new AuditOpinionDTO();
				odto.setDealUserName(dto.getCreatedBy());
				odto.setOpinionDesc(json.getString("opinionDesc"));
				odto.setProblemNo(dto.getProblemCode());
				odto.setOpinion(json.getString("opinion"));
				odto.setOpinionType(AuditConstants.opinionType_1);
				odto.setTaskType(AuditConstants.taskType_01);
				odto.setOpinionDesc(json.getString("opinionDesc"));
				commonDAO.update("opinoin.updateProblemOpinoin", odto);
				commonDAO.update("auditProblemsDao.updateAuditProblems", dto);
				resultMap.put(Constants.MSG_KEY, Constants.UPDATE_SUCCESS);
				resultMap.put(Constants.SUCCESS_RESULT_KEY,
						dto.getProblemCode());
			} else {
				String pn = randomCodeService.getCode(
						EventCodeUtil.event_codeSJ,
						EventCodeUtil.industry_type1);

				if (null != pn && !"".equals(pn)) {
					dto.setProblemCode(pn);
					dto.setRollbackFlag(AuditConstants.ROLLBACK_FLAG_DEFAULT);
					initWf(user, dto);
					commonDAO.insert("auditProblemsDao.insertAuditProblems",
							dto);
					// 保存意见信息
					AuditOpinionDTO odto = new AuditOpinionDTO();
					odto.setDealUserName(dto.getCreatedBy());
					odto.setOpinionDesc(json.getString("opinionDesc"));
					odto.setProblemNo(dto.getProblemCode());
					odto.setOpinion(json.getString("opinion"));
					odto.setOpinionType(AuditConstants.opinionType_1);
					odto.setTaskType(AuditConstants.taskType_01);
					odto.setOpinionDesc(json.getString("opinionDesc"));
					auditOpinionService.addOpinion(odto);
				}
				resultMap.put(Constants.MSG_KEY, Constants.INSERT_SUCCESS);
				resultMap.put(Constants.SUCCESS_RESULT_KEY, pn);
			}
			if (null != dto.getProblemCode()
					&& !"".equals(dto.getProblemCode())) {
				JSONArray array = JSON.parseArray(json.get("auditTargetDTO")
						.toString());
				saveAuditTarget(array, dto.getCreatedBy(), dto.getProblemCode());
				// 扣分
				json.put(AuditConstants.PROBLEM_CODE, dto.getProblemCode());
				json.put(AuditConstants.HAPPEN_DATE, dto.getHearDate());
				json.put(AuditConstants.PUNISH_DATESTART,
						dto.getPeriodBeginDate());
				json.put(AuditConstants.PUNISH_DATEEND, dto.getPeriodEndDate());
				integrityMedicalService.addIntegrityPoints(json,
						user.getUsername(), dto.getProblemCode(), "02");
			}
		} catch (Exception e) {
			BusinessServiceUtil.processException(e);
			e.printStackTrace();
		}
		return resultMap;
	}

	private void initWf(UserDetails user, AuditProblemsDTO dto)
			throws BusinessServiceException {
		if (AuditConstants.TEMP_FLAG_1.equals(dto.getTempFlag())) {
			dto.setProblemStatus(AuditConstants.problemStatus_0);
			// 不启动流程
			return;
		}
		dto.setProblemStatus(AuditConstants.problemStatus_3);
		// 启动流程{当为“保存操作”时，才会启动流程，暂存不会启动流程}
		HcpmsWorkFlowVO wfvo = new HcpmsWorkFlowVO();
		String beginType = "02"; // 表示稽核起始类型为录入
		Map<String, String> condition = new HashMap<String, String>();
		condition.put("AUDIT_BEGIN_TYPE", beginType);
		List<Authority> authorityList = user.getAuthorities();
		List<String> role = new ArrayList<String>();
		for (Authority authority : authorityList) {
			role.add(authority.getAuthority());
		}
		wfvo.setRole(role);
		wfvo.setTaskNo(dto.getProblemCode());
		wfvo.setTaskType(AuditConstants.TASK_TYPE_PROBLEM);
		wfvo.setActCurrent(user.getUsername());
		wfvo.setParamValue(condition);
		try {
			auditWorkFlowService.startWorkFlow(wfvo);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
			throw new BusinessServiceException();
		}
	}

	/**
	 * 
	 * @param array
	 */
	private void saveAuditTarget(JSONArray array, String loginName,
			String taskCode) {
		StringBuffer sbff = new StringBuffer();
		for (int i = 0; i < array.size(); i++) {
			JSONObject tempJson = array.getJSONObject(i);
			AuditTargetDTO dto = JSONObject.toJavaObject(tempJson,
					AuditTargetDTO.class);
			dto.setTaskCode(taskCode);
			dto.setUpdatedBy(loginName);
			dto.setCreatedBy(loginName);
			if ("1".equals(dto.getIsDeleted())) {
				sbff.append("'" + dto.getTargetCode() + "'").append(",");
			} else if ("1".equals(dto.getFlag())) {
				String uuid = commonDAO.getUUID();
				dto.setAuditTargetId(uuid);
				commonDAO.insert("auditTargetDao.insertAuditTarget", dto);
			}
		}
		if (sbff.length() > 0) {
			Map<String, Object> paramsMap = new HashMap<String, Object>();
			String ids = sbff.toString().substring(0,
					sbff.toString().length() - 1);
			paramsMap.put("ids", ids);
			paramsMap.put("updatedBy", loginName);
			commonDAO.update("auditTargetDao.deleteAuditTarget", paramsMap);
		}
	}

	@Override
	public Map<String, Object> saveAuditTarget(JSONObject json)
			throws BusinessServiceException {
		Map<String, Object> resultMap = null;
		try {
			AuditTargetDTO dto = JSONObject.toJavaObject(json,
					AuditTargetDTO.class);
			resultMap = new HashMap<String, Object>();
			if (dto.getAuditTargetId() != null
					&& "".equals(dto.getAuditTargetId().trim())) {
				commonDAO.update("auditTargetDao.updateAuditTarget", dto);
				resultMap.put(Constants.MSG_KEY, Constants.UPDATE_SUCCESS);
			} else {
				String uuid = commonDAO.getUUID();
				dto.setAuditTargetId(uuid);
				commonDAO.insert("auditTargetDao.insertAuditTarget", dto);
				resultMap.put("auditTargetId", uuid);
				resultMap.put(Constants.MSG_KEY, Constants.INSERT_SUCCESS);
			}
		} catch (Exception e) {
			BusinessServiceUtil.processException(e);
			e.printStackTrace();
		}
		return resultMap;
	}

	@SuppressWarnings("unchecked")
	@Override
	public Map<String, Object> queryAuditProblemsList(JSONObject transferJson,
			Map<String, Object> resultMap) throws BusinessServiceException {
		try {
			PaginationDTO pdto = new PaginationDTO();
			pdto.setQueryParams(JSONObject
					.toJavaObject(transferJson, Map.class));
			int page = Integer.parseInt(transferJson.getString("page"));
			int pageSize = Integer.parseInt(transferJson.getString("pageSize"));
			pdto.setEnd(pageSize * page);
			pdto.setStart(pageSize * (page - 1));
			pdto.setDoCount(true);
			pdto.setQueryAll(false);
			pdto.setLimit(pageSize);
			resultMap = commonDAO.queryPage(
					"auditProblemsDao.queryAuditProblemsList", pdto);
			resultMap.put(Constants.STATE_KEY, Constants.SUCCESS_STATE_VALUE);
			resultMap.put(Constants.MSG_KEY, Constants.SELECT_SUCCESS);
		} catch (Exception e) {
			BusinessServiceUtil.processException(e);
			e.printStackTrace();
		}
		return resultMap;
	}

	@Override
	public Map<String, Object> queryProblemList4Reg(int pageSize, int page,
			Map<String, Object> params) throws BusinessServiceException {

		PaginatedQueryDTO dto = new PaginatedQueryDTO();
		dto.setStart(pageSize);
		dto.setLimit(page);
		dto.setParam(params);
		return auditDao.queryPage("auditProblemsDao.queryProblemsListReg", dto);
	}

	@Override
	public Map<String, Object> queryAuditProblemsDetail(String auditProblemId,
			String problemCode) {
		Map<String, Object> resultMap = new HashMap<String, Object>();
		if (auditProblemId == null && problemCode == null) {
			resultMap.put(Constants.MSG_KEY, Constants.SELECT_FAILED);
			return resultMap;
		}
		if ("".equals(auditProblemId) && "".equals(problemCode)) {
			resultMap.put(Constants.MSG_KEY, Constants.SELECT_FAILED);
			return resultMap;
		}
		AuditProblemsDTO dto = new AuditProblemsDTO();
		dto.setProblemCode(problemCode);
		dto.setAuditProblemId(auditProblemId);
		AuditProblemsDTO rsl = (AuditProblemsDTO) commonDAO.get(
				"auditProblemsDao.queryAuditProblemsDetail", dto);
		AuditOpinionDTO padto = new AuditOpinionDTO();
		padto.setProblemNo(rsl.getProblemCode());
		padto.setOpinionType(AuditConstants.opinionType_1);
		padto.setTaskType(AuditConstants.taskType_01);
		AuditOpinionDTO adto = (AuditOpinionDTO) commonDAO.get(
				"opinoin.queryAuditOpinoinByParameter", padto);
		resultMap.put("result", rsl);
		resultMap.put("opinion", adto);
		resultMap.put(Constants.MSG_KEY, Constants.SELECT_SUCCESS);
		return resultMap;
	}

	@Override
	@SuppressWarnings("unchecked")
	public Map<String, Object> queryAuditTargetList(JSONObject json)
			throws BusinessServiceException {
		Map<String, Object> resultMap = null;
		try {
			AuditTargetDTO dto = JSONObject.toJavaObject(json,
					AuditTargetDTO.class);
			List<AuditTargetDTO> list = commonDAO.query(
					"auditProblemsDao.queryAuditTargetList", dto);
			resultMap = new HashMap<String, Object>();
			resultMap.put("result", list);
			resultMap.put(Constants.MSG_KEY, Constants.SELECT_SUCCESS);
		} catch (Exception e) {
			BusinessServiceUtil.processException(e);
			e.printStackTrace();
		}
		return resultMap;
	}

	@Override
	public String querySeqTaskNoByBizType(String businessType) {
		return (String) commonDAO.get("auditTargetDao.querySequence",
				businessType);
	}

	public Map<String, Object> queryAuditProblemBeanByParameterBean(int page,
			int pageSize, Map<String, Object> params, Map<String, Object> map)
			throws BusinessServiceException {
		PaginatedQueryDTO dto = new PaginatedQueryDTO();
		dto.setStart(pageSize);
		dto.setLimit(page);
		dto.setParam(params);
		map = auditDao.queryPage("auditProblemsDao.queryAuditProblemBean", dto);
		return map;
	}

	/*
	 * public long
	 * queryAuditProblemBeanCountByParameterBean(AuditProblemParameterRequestDTO
	 * requestBean) { QueryProblemDTOParameter parameter = new
	 * QueryProblemDTOParameter();
	 * 
	 * parameter.setCpNo(requestBean.getCpNo());
	 * parameter.setDoctorName(requestBean.getDoctorName());
	 * parameter.setSourceType(requestBean.getSourceType());
	 * parameter.setOrgCode(requestBean.getOrgCode());
	 * parameter.setOrgName(requestBean.getOrgName());
	 * parameter.setStartSubmitDate(requestBean.getStart());
	 * parameter.setEndSubmitDate(requestBean.getEnd());
	 * parameter.setProblemStatus(requestBean.getProblemStatus());
	 * 
	 * long count =
	 * this.auditProblemDao.queryAuditProblemBeanCount(requestBean);
	 * 
	 * return count; }
	 */

	@Override
	public Map<String, Object> queryCaseAuditList(int pageSize, int page,
			Map<String, Object> params) throws BusinessServiceException {
		PaginatedQueryDTO dto = new PaginatedQueryDTO();
		dto.setStart(pageSize);
		dto.setLimit(page);
		dto.setParam(params);
		return auditDao.queryPage("auditcase.findCaseList", dto);
	}

	@Override
	public String auditProblemsCancel(String problemCode, String problemStatus,
			UserDetails user) throws BusinessException {
		String msg = "";
		AuditProblemsDTO problem = new AuditProblemsDTO();
		problem.setProblemCode(problemCode);
		Map<String, Object> map = auditProblemDao
				.queryAuditProblems(problemCode);
		if (null == map) {
			return "没有该事件数据，请重新刷新或联系管理员!!!";
		}
		// 判断是否已经操作通过上一个流程
		if (null != map && problemStatus.equals(map.get("problemStatus"))) {
			HcpmsStorageDTO dto = new HcpmsStorageDTO();
			// dto.setModuleType(AuditConstants.sjModule);
			dto.setBusinessId(problemCode);
			if (problemStatus.equals(AuditConstants.problemStatus_5)) {
				if (!user.getUsername().equals(map.get("appointFirst"))) {
					return "您没有权限撤回该事件,如需撤回请联系相关人员";
				}
				// dto.setChildModuleType(AuditConstants.review);
				// dto.setBusinessType(AuditConstants.opinionType_4);
				problem.setProblemStatus(AuditConstants.problemStatus_4);
			} else if (problemStatus.equals(AuditConstants.problemStatus_6)) {
				if (!user.getUsername().equals(map.get("appointSecond"))) {
					return "您没有权限撤回该事件,如需撤回请联系相关人员";
				}
				// dto.setChildModuleType(AuditConstants.examine);
				// dto.setBusinessType(AuditConstants.opinionType_5);
				problem.setProblemStatus(AuditConstants.problemStatus_5);
			} else {
				return "撤回失败，该事件不能进行撤回操作，请刷新之后进行操作!!!";
			}

			problem.setUpdatedBy(user.getUsername());
			// 工作流方法
			try {
				auditWorkFlowService.processWorkFlow(problemCode, user, user
						.getUsername(), null, AuditConstants.TASK_TYPE_PROBLEM,
						(String) AuditWfContentsUtil.EVENT_STATUS_NODE
								.get(problemStatus));
			} catch (Exception e) {
				throw new BusinessException(e.getMessage());
			}

			// 删除上级暂存的数据
			hcpmsStorageService.deleteStorageData(dto);
			// 更新事件状态
			auditProblemDao.updateAuditProblem(problem);
		} else {
			msg = "撤回失败，该事件可能已经复核或者审核完成不能再进行撤回操作，请刷新页面!!!";
		}
		return msg;
	}

	@Override
	public Map<String, Object> batchEventsInitWf(JSONObject json,
			UserDetails user) throws BusinessServiceException {
		Map<String, Object> resultMap = new HashMap<String, Object>();

		AuditProblemsDTO dto = new AuditProblemsDTO();

		dto.setProblemStatus(AuditConstants.problemStatus_3);
		// 启动流程{当为“保存操作”时，才会启动流程，暂存不会启动流程}
		HcpmsWorkFlowVO wfvo = new HcpmsWorkFlowVO();
		String beginType = "02"; // 表示稽核起始类型为录入
		Map<String, String> condition = new HashMap<String, String>();
		condition.put("AUDIT_BEGIN_TYPE", beginType);
		List<Authority> authorityList = user.getAuthorities();
		List<String> role = new ArrayList<String>();
		for (Authority authority : authorityList) {
			role.add(authority.getAuthority());
		}
		wfvo.setRole(role);
		wfvo.setTaskType(AuditConstants.TASK_TYPE_PROBLEM);
		wfvo.setActCurrent(user.getUsername());
		wfvo.setParamValue(condition);
		JSONArray array = JSON.parseArray(json.get("problemCodes").toString());
		// koufen
		Map<String, Object> scoreMap = new HashMap<String, Object>();
		HcpmsStorageDataDTO sto = new HcpmsStorageDataDTO();
		scoreMap.put("caseType", "02");// 01:预警，02：稽核
		scoreMap.put("userName", user.getUsername());// 当前操作人
		AuditOpinionDTO opinionDTO = new AuditOpinionDTO();
		opinionDTO.setOpinionType(AuditConstants.opinionType_1);
		opinionDTO.setTaskType(AuditConstants.taskType_01);
		StringBuffer sbf = new StringBuffer();
		for (Object ost : array) {
			opinionDTO.setProblemNo(ost.toString());
			List<AuditOpinionDTO> al = commonDAO.query(
					"opinoin.queryAuditOpinoinByParameter", opinionDTO);
			if (al.size() == 0) {
				sbf.append("事件编号：").append(ost.toString())
						.append(" 数据校验不通过,请校验后再提交！\n");
				continue;
			}
			scoreMap.put("caseNo", ost.toString());// 案件号
			dto.setProblemCode(ost.toString());
			wfvo.setTaskNo(ost.toString());
			sto.setBusinessId(ost.toString());
			try {
				auditWorkFlowService.startWorkFlow(wfvo);
				integrityMedicalService.batchAddPointCutTemps(scoreMap);
				commonDAO.update("auditProblemsDao.updateAuditProblems", dto);
				storageService.deleteStorageDate(sto);
			} catch (Exception e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				throw new BusinessServiceException();
			}
		}
		if (sbf.length() == 0) {
			resultMap.put(Constants.MSG_KEY, "批量提交成功!");
		} else {
			resultMap.put(Constants.MSG_KEY, sbf.toString());
		}
		resultMap.put(Constants.SUCCESS_RESULT_KEY, dto.getProblemCode());
		return resultMap;
	}
}
